package com.example.musicaiap.ui.player

import android.util.Log
import androidx.media3.common.MediaItem
import androidx.media3.common.Player
import com.example.musicaiap.data.repository.FavoriteStateRepository
import com.example.musicaiap.data.repository.MusicRepository
import com.example.musicaiap.data.repository.RoomMusicRepository
import com.example.musicaiap.domain.model.Song
import com.example.musicaiap.service.MediaBrowserHelper
import com.example.musicaiap.service.PlaybackState
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import javax.inject.Inject
import javax.inject.Singleton
import kotlin.random.Random

/**
 * 播放器控制器，管理播放状态和处理播放相关操作
 * 与PlayerViewModel分离，避免ViewModel互相注入的问题
 */
@Singleton
class PlayerController @Inject constructor(
    private val mediaBrowserHelper: MediaBrowserHelper,
    private val musicRepository: MusicRepository,
    private val favoriteStateRepository: FavoriteStateRepository
) {
    private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Main)

    private val _playerState = MutableStateFlow(PlayerState())
    val playerState: StateFlow<PlayerState> = _playerState.asStateFlow()

    private val _playerEffect = MutableStateFlow<PlayerEffect?>(null)
    val playerEffect: StateFlow<PlayerEffect?> = _playerEffect.asStateFlow()

    private val _playbackState = MutableStateFlow<PlaybackState>(PlaybackState.Initial)
    val playbackState: StateFlow<PlaybackState> = _playbackState.asStateFlow()

    private val _playbackCompleted = Channel<Unit>()
    val playbackCompleted: Flow<Unit> = _playbackCompleted.receiveAsFlow()

    private var currentPlayMode: PlayerContract.PlayMode = PlayerContract.PlayMode.SEQUENCE

    // 注意：我们不再使用内部缓存，而是直接使用FavoriteStateRepository
    // private val favoriteStates = mutableMapOf<String, Boolean>()

    init {
        // 连接媒体浏览器
        connectMediaBrowser()

        // 监听播放状态变化
        mediaBrowserHelper.playbackState
            .onEach { playbackState ->
                when (playbackState) {
                    is PlaybackState.Initial -> {
                        // 初始状态，不做处理
                    }
                    is PlaybackState.Ready -> {
                        updatePlayerState(playbackState)
                    }
                    is PlaybackState.Error -> {
                        sendEffect(PlayerEffect.PlaybackError(playbackState.message))
                    }
                    is PlaybackState.Buffering -> {
                        // 缓冲状态，暂时不处理
                    }
                    is PlaybackState.Ended -> {
                        // 播放结束，发送播放完成事件
                        sendEffect(PlayerEffect.PlaybackCompleted)
                        handlePlaybackCompleted()
                    }
                }
            }
            .launchIn(scope)

        scope.launch {
            mediaBrowserHelper.playbackState.collect { state ->
                _playbackState.value = state
            }
        }

        scope.launch {
            mediaBrowserHelper.isConnected.collect { isConnected ->
                if (isConnected) {
                    // 连接成功后，可以开始播放
                    _playerState.value = _playerState.value.copy(isConnected = true)
                } else {
                    // 连接断开，更新状态
                    _playerState.value = _playerState.value.copy(isConnected = false)
                }
            }
        }

        // 监听收藏状态仓库中的状态变化
        scope.launch {
            favoriteStateRepository.currentFavoriteState.collect { isFavorite ->
                // 更新当前播放状态
                _playerState.value = _playerState.value.copy(isFavorite = isFavorite)
            }
        }

        // 同时监听所有歌曲的收藏状态变化事件
        scope.launch {
            favoriteStateRepository.favoriteChanges.collect { event ->
                // 不再需要更新内存缓存，直接使用FavoriteStateRepository
                // favoriteStates[event.songId] = event.isFavorite

                // 如果是当前播放的歌曲，更新UI状态
                if (_playerState.value.currentSong?.id == event.songId) {
                    _playerState.value = _playerState.value.copy(isFavorite = event.isFavorite)
                }
            }
        }
    }

    /**
     * 连接媒体浏览器
     */
    private fun connectMediaBrowser() {
        scope.launch {
            mediaBrowserHelper.connect()
        }
    }

    /**
     * 播放单首歌曲
     * @param song 要播放的歌曲
     * @param playlistSource 播放列表来源
     */
    fun play(song: Song, playlistSource: String = "SINGLE") {
        scope.launch {
            mediaBrowserHelper.connect()
            mediaBrowserHelper.playSong(song)
            // 更新播放列表来源
            _playerState.value = _playerState.value.copy(playlistSource = playlistSource)
        }
    }

    /**
     * 播放歌曲列表
     * @param songs 要播放的歌曲列表
     * @param startIndex 开始播放的索引
     * @param playlistSource 播放列表来源
     */
    fun play(songs: List<Song>, startIndex: Int = 0, playlistSource: String = "PLAYLIST") {
        scope.launch {
            if (songs.isEmpty()) return@launch

            mediaBrowserHelper.connect()
            mediaBrowserHelper.playPlaylist(songs, startIndex)

            // 更新当前播放列表和来源
            _playerState.value = _playerState.value.copy(
                currentPlaylist = songs,
                playlistSource = playlistSource
            )

            // 保存播放列表状态到数据库
            if (musicRepository is RoomMusicRepository) {
                try {
                    val currentSongId = songs[startIndex].id
                    val sourceId = when (playlistSource) {
                        "LOCAL" -> "local_playlist"
                        "FAVORITES" -> "favorites_playlist"
                        "PLAYLIST" -> songs[0].id // 使用第一首歌曲ID作为播放列表ID
                        else -> ""
                    }

                    (musicRepository as RoomMusicRepository).saveCurrentPlaylist(
                        sourceType = playlistSource,
                        sourceId = sourceId,
                        currentSongId = currentSongId
                    )
                } catch (e: Exception) {
                    Log.e("PlayerController", "保存播放列表状态失败: ${e.message}")
                }
            }
        }
    }

    /**
     * 播放/暂停切换
     */
    fun togglePlayPause() {
        scope.launch {
            mediaBrowserHelper.togglePlayPause()
        }
    }

    /**
     * 跳到下一首
     */
    fun skipToNext() {
        scope.launch {
            mediaBrowserHelper.seekTo(0)
        }
    }

    /**
     * 跳到上一首
     */
    fun skipToPrevious() {
        scope.launch {
            mediaBrowserHelper.seekTo(0)
        }
    }

    /**
     * 跳到指定位置
     */
    fun seekTo(position: Long) {
        scope.launch {
            mediaBrowserHelper.seekTo(position)
        }
    }

    /**
     * 切换播放速度
     */
    fun setPlaybackSpeed(speed: Float) {
        scope.launch {
            mediaBrowserHelper.setPlaybackSpeed(speed)
        }
    }

    /**
     * 设置重复模式
     */
    fun setRepeatMode(repeatMode: Int) {
        scope.launch {
            mediaBrowserHelper.setRepeatMode(repeatMode)
        }
    }

    /**
     * 设置随机播放
     */
    fun setShuffleMode(enabled: Boolean) {
        scope.launch {
            mediaBrowserHelper.setShuffleMode(enabled)
        }
    }

    /**
     * 切换收藏状态
     * 优化版本：简化状态处理逻辑，使用FavoriteStateRepository作为单一数据源
     */
    fun toggleFavorite(songId: String) {
        scope.launch {
            try {
                // 获取当前状态（直接从FavoriteStateRepository获取）
                val currentState = favoriteStateRepository.getSongFavoriteState(songId)

                // 立即更新UI状态，提供即时反馈
                val newState = !currentState

                // 先更新Repository状态，这会触发UI和通知栏的更新
                favoriteStateRepository.setSongFavoriteState(songId, newState)

                // 在后台执行实际的数据库操作
                val actualState = withContext(Dispatchers.IO) {
                    musicRepository.toggleFavorite(songId)
                }

                // 确保最终状态与数据库一致
                if (actualState != newState) {
                    favoriteStateRepository.setSongFavoriteState(songId, actualState)
                }

                // 发送状态变更效果
                sendEffect(PlayerEffect.FavoriteChanged(actualState))

            } catch (e: Exception) {
                // 如果操作失败，恢复到原始状态
                val actualState = withContext(Dispatchers.IO) {
                    musicRepository.isSongFavorite(songId)
                }
                favoriteStateRepository.setSongFavoriteState(songId, actualState)

                sendEffect(PlayerEffect.PlaybackError("收藏操作失败：${e.message}"))
            }
        }
    }

    /**
     * 更新播放器状态
     */
    private fun updatePlayerState(playbackState: PlaybackState.Ready) {
        val currentSong = playbackState.currentMediaItem?.let { mediaItem ->
            Song(
                id = mediaItem.mediaId,
                title = mediaItem.mediaMetadata.title?.toString() ?: "",
                artist = mediaItem.mediaMetadata.artist?.toString() ?: "",
                album = mediaItem.mediaMetadata.albumTitle?.toString() ?: "",
                duration = playbackState.duration,
                coverUrl = mediaItem.mediaMetadata.artworkUri?.toString() ?: "",
                url = mediaItem.requestMetadata.mediaUri?.toString() ?: ""
            )
        }

        // 获取当前歌曲的收藏状态
        val songId = currentSong?.id

        if (songId != null) {
            // 设置当前歌曲ID到收藏状态仓库
            favoriteStateRepository.setCurrentSong(songId)

            // 异步加载收藏状态
            scope.launch {
                try {
                    val isFavorite = withContext(Dispatchers.IO) {
                        musicRepository.isSongFavorite(songId)
                    }

                    // 不再需要更新内存缓存，直接使用FavoriteStateRepository
                    // favoriteStates[songId] = isFavorite

                    // 更新收藏状态仓库
                    favoriteStateRepository.initSongFavoriteState(songId, isFavorite)

                } catch (e: Exception) {
                    // 处理错误
                    Log.e("PlayerController", "加载收藏状态失败: ${e.message}")
                }
            }
        }

        // 立即更新其他状态，避免UI等待
        val cachedIsFavorite = songId?.let { favoriteStateRepository.getSongFavoriteState(it) } ?: false

        // 保留当前播放列表
        val currentPlaylist = _playerState.value.currentPlaylist ?: emptyList()
        val playlistSource = _playerState.value.playlistSource

        _playerState.value = _playerState.value.copy(
            currentSong = currentSong,
            isPlaying = playbackState.isPlaying,
            currentPosition = playbackState.currentPosition,
            duration = playbackState.duration,
            isFavorite = cachedIsFavorite,
            currentPlaylist = currentPlaylist // 保留当前播放列表而不是重置
        )
    }

    /**
     * 发送副作用
     */
    private fun sendEffect(effect: PlayerEffect) {
        scope.launch {
            _playerEffect.value = effect
        }
    }

    /**
     * 释放资源
     */
    fun dispose() {
        scope.launch {
            mediaBrowserHelper.disconnect()
        }
    }

    fun setPlayMode(mode: PlayerContract.PlayMode) {
        currentPlayMode = mode
        sendEffect(PlayerEffect.PlayModeChanged(mode))
    }

    fun getPlayMode(): PlayerContract.PlayMode = currentPlayMode

    private fun handlePlaybackCompleted() {
        scope.launch {
            when (currentPlayMode) {
                PlayerContract.PlayMode.SEQUENCE -> {
                    // 顺序播放，播放下一首
                    mediaBrowserHelper.seekTo(0)
                    mediaBrowserHelper.connect()
                }
                PlayerContract.PlayMode.SHUFFLE -> {
                    // 随机播放，随机选择一首
                    val currentPlaylist = _playerState.value.currentPlaylist
                    if (currentPlaylist?.isNotEmpty() == true) {
                        val randomIndex = Random.nextInt(currentPlaylist.size)
                        mediaBrowserHelper.seekTo(0)
                        mediaBrowserHelper.connect()
                    }
                }
                PlayerContract.PlayMode.REPEAT_ONE -> {
                    // 单曲循环，重新播放当前歌曲
                    mediaBrowserHelper.seekTo(0)
                    mediaBrowserHelper.connect()
                }
                PlayerContract.PlayMode.REPEAT_ALL -> {
                    // 列表循环，播放下一首
                    mediaBrowserHelper.seekTo(0)
                    mediaBrowserHelper.connect()
                }
            }
        }
    }

    fun stop() {
        scope.launch {
            mediaBrowserHelper.seekTo(0)
        }
    }

    fun pause() {
        scope.launch {
            mediaBrowserHelper.seekTo(0)
        }
    }

    fun resume() {
        scope.launch {
            mediaBrowserHelper.connect()
        }
    }

    suspend fun isSongFavorite(songId: String): Boolean {
        return withContext(Dispatchers.IO) {
            if (musicRepository is RoomMusicRepository) {
                (musicRepository as RoomMusicRepository).isSongFavorite(songId)
            } else {
                false
            }
        }
    }
}

/**
 * 播放器状态
 */
data class PlayerState(
    val currentSong: Song? = null,
    val currentMediaItem: MediaItem? = null,
    val playbackState: Int = Player.STATE_IDLE,
    val isPlaying: Boolean = false,
    val currentPosition: Long = 0,
    val duration: Long = 0,
    val playbackSpeed: Float = 1.0f,
    val repeatMode: Int = Player.REPEAT_MODE_OFF,
    val shuffleModeEnabled: Boolean = false,
    val isFavorite: Boolean = false,
    val error: String? = null,
    val currentPlaylist: List<Song>? = null,
    val isConnected: Boolean = false,
    val playlistSource: String = "" // 播放列表来源："LOCAL", "FAVORITES", "PLAYLIST", "SINGLE"
)

/**
 * 播放器副作用
 */
sealed interface PlayerEffect {
    data class PlaybackError(val message: String) : PlayerEffect
    data class MediaItemTransition(val song: Song?) : PlayerEffect
    object PlaybackCompleted : PlayerEffect
    data class FavoriteChanged(val isFavorite: Boolean) : PlayerEffect
    data class PlayModeChanged(val mode: PlayerContract.PlayMode) : PlayerEffect
}